package net.stogi.unicore.beyond.ui.client;

import java.util.HashMap;
import java.util.Map;

import net.stogi.common.gwt.dispatch.client.core.ActionManager;
import net.stogi.common.gwt.frame.client.core.AbstractApplicationManager;
import net.stogi.common.gwt.frame.client.core.CacheManager;
import net.stogi.common.gwt.frame.client.core.EventBus;
import net.stogi.common.gwt.frame.client.core.LayoutManager;
import net.stogi.common.gwt.frame.client.module.Module;
import net.stogi.common.gwt.frame.client.module.ModuleFactoryRegistry;
import net.stogi.common.gwt.frame.client.module.ModuleFactory.ModuleInstanceCallback;
import net.stogi.unicore.beyond.ui.client.taskeditor.editormenu.EditorMenuModule;
import net.stogi.unicore.beyond.ui.client.taskeditor.editormenu.EditorMenuModuleFactory;
import net.stogi.unicore.beyond.ui.client.taskeditor.iotoolbox.IoToolboxModule;
import net.stogi.unicore.beyond.ui.client.taskeditor.iotoolbox.IoToolboxModuleFactory;
import net.stogi.unicore.beyond.ui.client.taskeditor.propertyeditor.PropertyEditorModule;
import net.stogi.unicore.beyond.ui.client.taskeditor.propertyeditor.PropertyEditorModuleFactory;
import net.stogi.unicore.beyond.ui.client.taskeditor.taskoutline.TaskOutlineModule;
import net.stogi.unicore.beyond.ui.client.taskeditor.taskoutline.TaskOutlineModuleFactory;
import net.stogi.unicore.beyond.ui.client.taskeditor.taskpreview.TaskPreviewModule;
import net.stogi.unicore.beyond.ui.client.taskeditor.taskpreview.TaskPreviewModuleFactory;
import net.stogi.unicore.beyond.ui.client.taskrunner.runnermenu.RunnerMenuModule;
import net.stogi.unicore.beyond.ui.client.taskrunner.runnermenu.RunnerMenuModuleFactory;
import net.stogi.unicore.beyond.ui.client.taskrunner.taskinstance.TaskInstanceModule;
import net.stogi.unicore.beyond.ui.client.taskrunner.taskinstance.TaskInstanceModuleFactory;

public class UnicoreBeyondUiApplicationManagerImpl extends AbstractApplicationManager {

	private final Map<Class<? extends Module>, Module> moduleMap = new HashMap<Class<? extends Module>, Module>();

	public UnicoreBeyondUiApplicationManagerImpl(ActionManager actionManager, CacheManager cacheManager, EventBus eventBus,
			LayoutManager layoutManager, ModuleFactoryRegistry moduleFactoryRegistry) {
		super(actionManager, cacheManager, eventBus, layoutManager, moduleFactoryRegistry);
		initFactories();
		initHandlers();
		initModules();
	}

	@Override
	public void run() {
		layoutManager.layout();
	}

	@Override
	protected void initFactories() {
		// Task Editor.
		moduleFactoryRegistry.registerFactory(EditorMenuModule.class, new EditorMenuModuleFactory(actionManager, eventBus));
		moduleFactoryRegistry.registerFactory(IoToolboxModule.class, new IoToolboxModuleFactory(actionManager, eventBus));
		moduleFactoryRegistry.registerFactory(PropertyEditorModule.class, new PropertyEditorModuleFactory(actionManager, eventBus));
		moduleFactoryRegistry.registerFactory(TaskOutlineModule.class, new TaskOutlineModuleFactory(actionManager, eventBus));
		moduleFactoryRegistry.registerFactory(TaskPreviewModule.class, new TaskPreviewModuleFactory(actionManager, eventBus));
		// Task Runner.
		moduleFactoryRegistry.registerFactory(RunnerMenuModule.class, new RunnerMenuModuleFactory(actionManager, eventBus));
		moduleFactoryRegistry.registerFactory(TaskInstanceModule.class, new TaskInstanceModuleFactory(actionManager, eventBus));
	}

	@Override
	protected void initHandlers() {}

	@Override
	protected void initModules() {
		moduleFactoryRegistry.findFactory(EditorMenuModule.class).getInstance(new ModuleInstanceCallback<EditorMenuModule>() {

			@Override
			public void onModuleInstanceCreated(EditorMenuModule module) {
				moduleMap.put(EditorMenuModule.class, module);
				layoutManager.addWidget("editor.west", module.getWidget(EditorMenuModule.EDITOR_MENU_WIDGET));
			}

			@Override
			public void onBeforeModuleInstanceCreated() {}
		});
		moduleFactoryRegistry.findFactory(IoToolboxModule.class).getInstance(new ModuleInstanceCallback<IoToolboxModule>() {

			@Override
			public void onModuleInstanceCreated(IoToolboxModule module) {
				moduleMap.put(IoToolboxModule.class, module);
				layoutManager.addWidget("editor.west", module.getWidget(IoToolboxModule.IO_TOOLBOX_WIDGET));
			}

			@Override
			public void onBeforeModuleInstanceCreated() {}
		});
		moduleFactoryRegistry.findFactory(TaskOutlineModule.class).getInstance(new ModuleInstanceCallback<TaskOutlineModule>() {

			@Override
			public void onModuleInstanceCreated(TaskOutlineModule module) {
				moduleMap.put(TaskOutlineModule.class, module);
				layoutManager.addWidget("editor.east", module.getWidget(TaskOutlineModule.TASK_OUTLINE_WIDGET));
			}

			@Override
			public void onBeforeModuleInstanceCreated() {}
		});
		moduleFactoryRegistry.findFactory(PropertyEditorModule.class).getInstance(new ModuleInstanceCallback<PropertyEditorModule>() {

			@Override
			public void onModuleInstanceCreated(PropertyEditorModule module) {
				moduleMap.put(PropertyEditorModule.class, module);
				layoutManager.addWidget("editor.east", module.getWidget(PropertyEditorModule.PROPERTY_VIEWER_WIDGET));
			}

			@Override
			public void onBeforeModuleInstanceCreated() {}
		});
		moduleFactoryRegistry.findFactory(TaskPreviewModule.class).getInstance(new ModuleInstanceCallback<TaskPreviewModule>() {

			@Override
			public void onModuleInstanceCreated(TaskPreviewModule module) {
				moduleMap.put(TaskPreviewModule.class, module);
			}

			@Override
			public void onBeforeModuleInstanceCreated() {}
		});
		moduleFactoryRegistry.findFactory(RunnerMenuModule.class).getInstance(new ModuleInstanceCallback<RunnerMenuModule>() {

			@Override
			public void onModuleInstanceCreated(RunnerMenuModule module) {
				moduleMap.put(RunnerMenuModule.class, module);
				layoutManager.addWidget("runner.west", module.getWidget(RunnerMenuModule.RUNNER_MENU_WIDGET));
			}

			@Override
			public void onBeforeModuleInstanceCreated() {}
		});
		
		moduleFactoryRegistry.findFactory(TaskInstanceModule.class).getInstance(new ModuleInstanceCallback<TaskInstanceModule>() {

			@Override
			public void onModuleInstanceCreated(TaskInstanceModule module) {
				moduleMap.put(TaskInstanceModule.class, module);
			}

			@Override
			public void onBeforeModuleInstanceCreated() {}
		});
	}
}
